#ifndef TC_ALLOCATOR_CPP
#define TC_ALLOCATOR_CPP

/** \file Allocator.cpp
 * Definitions for the templated class Allocator.
 *
 * (C) Copyright  Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 *
 * $Id: Allocator.cpp 117 2006-06-19 06:49:41Z semihc $
 *
 * Partly derived from N.M.Josuttis' work:
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 */


#include "Allocator.hpp"
#include <limits>
#include <iostream>
#include "Assert.hpp"


namespace TC {

  // return maximum number of elements that can be allocated
  template <typename T>
  typename Allocator<T>::size_type 
  Allocator<T>::max_size() const // throw() 
  {
#   ifdef TC_NO_STD_NUMERIC_LIMITS
     // To make sure INT_MAX is proper maximum
     TC_ASSERT_COMPILE( sizeof(int)==sizeof(std::size_t) );
     return INT_MAX / sizeof(T);
#   else
     return std::numeric_limits<size_type>::max() / sizeof(T);
#   endif
  }

  template <typename T>
  typename Allocator<T>::size_type 
  Allocator<T>::max_size (size_type size) const // throw()
  {
#   ifdef TC_COMP_Forte
     return 1 > UINT_MAX/size ? size_type(1) : size_type(UINT_MAX/size);
#   elif defined(TC_NO_STD_NUMERIC_LIMITS)
     // To make sure INT_MAX is proper maximum
     TC_ASSERT_COMPILE( sizeof(int)==sizeof(std::size_t) );
     return INT_MAX / size;
#   else
     return std::numeric_limits<size_type>::max() / size;
#   endif
  }

  // Allocate but don't initialize num elements of type T
  template <typename T>
  typename Allocator<T>::pointer 
  Allocator<T>::allocate(size_type num, const void* /*ptr*/) 
  {
    // with global new
    return static_cast<pointer>(::operator new(num*sizeof(T)));
  }

  // Initialize elements of allocated storage p with value
  template <typename T>
  void Allocator<T>::construct(pointer p, const T& value) 
  {
    // with placement new
    new (static_cast<void*>(p)) T(value);
  }

  // Destroy elements of initialized storage p
  template <typename T>
  void Allocator<T>::destroy(pointer p) {
    // by calling their destructor
    p->~T();
  }

  // Deallocate storage p of deleted elements
  template <typename T>
  void Allocator<T>::deallocate(pointer p, size_type /*num*/) 
  {
    // with global delete
    ::operator delete(static_cast<void*>(p));
  }


} // end namespace

#endif /* TC_ALLOCATOR_CPP */
